//---------------------------------------------------------------------------
//
// Copyright (C) Microsoft Corporation.  All rights reserved.
//
//---------------------------------------------------------------------------

using System;
using System.ComponentModel;


namespace PlanetWPF.Toolbelt.Controls
{
    /// <summary>
    /// PowerCalendarDate is a wrapper over DateTime
    /// </summary>
    /// <remarks>
    /// The main purpose of PowerCalendarDate is to increase the PowerMonthCalendar's scroll perf.
    /// It is used to only update Date object and fire a PropertyChanged event, 
    /// so when user scroll month, the selectedDates UI items won't be regenerated
    /// </remarks>
    public sealed class PowerCalendarDate : INotifyPropertyChanged
    {
        private DateTime    m_Date;
        private bool        m_IsOtherMonth;
        private bool        m_IsSelectable = true;
        private object      m_Data;

        #region Constructors

        /// <summary>
        /// Constructor
        /// </summary>
        public PowerCalendarDate(DateTime date)
        {
            m_Date = date;
        }

        #endregion

        #region Public Properties/Events/Methods

        /// <summary>
        /// This event is raised when PowerCalendarDate.Date has changed.
        /// </summary>
        public event PropertyChangedEventHandler PropertyChanged;

        /// <summary>
        /// DateTime
        /// </summary>
        public DateTime Date
        {
            get { return m_Date; }
            internal set
            {
                if (m_Date != value)
                {
                    DateTime oldDate = m_Date;
                    m_Date = value;
                    OnPropertyChanged("Date");
                    if (IsDateToday(oldDate) != IsDateToday(m_Date))
                    {
                        OnPropertyChanged("IsToday");
                    }

                    if (IsDateWeekend(oldDate) != IsDateWeekend(m_Date))
                    {
                        OnPropertyChanged("IsWeekend");
                    }
                }
            }
        }

        /// <summary>
        /// Indicates whether this selectedDate is a month other than the month displayed in the PowerMonthCalendar control
        /// </summary>
        public bool IsOtherMonth
        {
            get { return m_IsOtherMonth; }
            internal set
            {
                if (m_IsOtherMonth != value)
                {
                    m_IsOtherMonth = value;
                    OnPropertyChanged("IsOtherMonth");
                }
            }
        }

        /// <summary>
        /// Indicates whether this selectedDate should be enabled or not. (This value is used to disable the selectedDate out of Max/MinDate)
        /// </summary>
        public bool IsSelectable
        {
            get { return m_IsSelectable; }
            internal set
            {
                if (m_IsSelectable != value)
                {
                    m_IsSelectable = value;
                    OnPropertyChanged("IsSelectable");
                }
            }
        }

        /// <summary>
        /// Indicates wheter the selectedDate is the same selectedDate specified by the 
        /// </summary>
        public bool IsToday
        {
            get { return IsDateToday(m_Date); }
        }

        /// <summary>
        /// Indicates whether the selectedDate is a either Saturday or Sunday
        /// </summary>
        public bool IsWeekend
        {
            get { return IsDateWeekend(m_Date); }
        }

        /// <summary>
        /// 
        /// </summary>
        public object Data
        {
            get { return m_Data; }
            internal set
            {
                m_Data = value;
                OnPropertyChanged("Data");
            }
        }

        /// <summary>
        /// Return string representation of this selectedDate
        /// </summary>
        public override string ToString()
        {
            return m_Date.ToShortDateString();
        }

        #endregion

        #region Internal Properties/Methods

        /// <summary>
        /// Update Date and IsValid property
        /// </summary>
        internal void InternalUpdate(PowerCalendarDate cdate)
        {
            Date = cdate.Date;
            IsOtherMonth = cdate.IsOtherMonth;
            IsSelectable = cdate.IsSelectable;
        }

        #endregion

        private void OnPropertyChanged(String info)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs(info));
        }

        private bool IsDateWeekend(DateTime date)
        {
            return date.DayOfWeek == DayOfWeek.Saturday || date.DayOfWeek == DayOfWeek.Sunday;
        }

        private bool IsDateToday(DateTime date)
        {
            return PowerMonthCalendarHelper.CompareYearMonthDay(date, DateTime.Now) == 0;
        }

    }
}